package main

import (
	"cloudops/src/agent"
	"cloudops/src/agent/cron"
	"cloudops/src/agent/job"
	"cloudops/src/common"
	"cloudops/src/config"
	"cloudops/src/web"
	"context"
	"flag"
	esl "github.com/ning1875/errgroup-signal/signal"
	"go.uber.org/zap"
)

func main() {
	// 主配置文件和命令行参数
	var configFile string
	flag.StringVar(&configFile, "agent_config_file", "./agent.yml", "配置文件路径")
	flag.Parse()

	// 初始化配置文件
	sc, err := config.LoadAgent(configFile)
	if err != nil {
		sc.Logger.Error("加载配置文件失败，失败:", zap.Error(err))
		return
	}

	// 获取主机名和IP地址
	hostName := common.GetHostName()
	localIp := common.GetLocalIp()
	sc.HostName = hostName
	sc.LocalIp = localIp

	// 初始化日志记录器，并添加主机名和IP地址标识
	logger := common.NewZaplogger(sc.LogLevel, sc.LogFilePath, sc.ErrLogPath).With(
		zap.String("hostName", sc.HostName),
		zap.String("localIp", sc.LocalIp),
	)

	defer logger.Sync()
	sc.Logger = logger // 设置配置文件中的日志记录器
	logger.Info("解析代理配置文件成功，日志记录器初始化成功")
	//logger.Error("测试错误日志记录")

	// 创建客户端
	client := agent.NewGrpcClient(sc)
	// 先初始化这个taskManager
	tm := job.NewTaskManager(sc)
	cm := cron.NewCronManager(client, tm)

	// 创建信号监听组
	group, stopChan := esl.SetupStopSignalContext()
	ctxAll, cancelAll := context.WithCancel(context.Background())

	// 监听退出信号
	group.Go(func() error {
		logger.Info("开始监听停止信号")
		for {
			select {
			case <-stopChan:
				logger.Info("捕获退出信号，通知所有任务退出")
				cancelAll()
				return nil
			}
		}
	})

	{
		if sc.InfoCollectC.Enable {
			group.Go(func() error {
				logger.Info("开始启动信息采集任务")
				err := cm.InfoReportMagager(ctxAll)
				if err != nil {
					logger.Error("信息采集任务发生错误", zap.Error(err))
				}
				return err
			})
		} else {
			logger.Info("未开启信息采集任务")
		}
	}

	group.Go(func() error {
		errChan := make(chan error)
		go func() {
			errChan <- web.AgentStartGin(sc)
		}()
		logger.Info("Web 服务启动成功")
		select {
		case err := <-errChan:
			logger.Error("Agent Gin 发生错误", zap.Error(err))
			return err
		case <-ctxAll.Done():
			logger.Info("收到退出信号，Gin 退出")
			return nil
		}
	})

	{
		if sc.JobExecC.Enable {
			logger.Info("开始启动任务执行模块")
			// 任务执行模块
			job.MockTaskRun(sc)
			group.Go(func() error {
				err := cm.JobExecManager(ctxAll)
				if err != nil {
					logger.Error("任务执行模块发生错误", zap.Error(err))
				}
				return err
			})
		} else {
			logger.Info("未开启任务执行模块")
		}
	}

	// 等待所有任务退出
	group.Wait()
}
